﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.IO;

namespace Logger
{
    /// <summary>
    /// XML Gateway class that provides a XML access to upperlayer applications as a Facade
    /// </summary>
    /// <dates>
    /// 15/05/2011 - created by Chiaki Sato
    /// </dates>
    class XmlDaoGateway : IXmlDaoGateway
    {

        private const string LOG_FILE_NAME = "xmllogger_{0}.xml";
        private const string LOG_FILE_NAME_DATE_FORMAT = "yyyyMMdd";
        private const string ELEMENT_ROOT = "FrankensteamXmlLogger";
        private const string ELEMENT_PARENT = "Log";
        private const string ESC_BACKSLASH = @"\";

        private static XmlDaoGateway xmlDaoGatewaySingleton = new XmlDaoGateway();
        private XmlDocument xmlDoc = new XmlDocument();
        private XmlElement eRoot;
        private XmlElement eParent;
        private string xmlPath;
        private string xmlFile;

        /// <summary>
        /// Default constructor for XmlLogger class.
        /// Log files will be created in this application directory as default. 
        /// </summary>
        private XmlDaoGateway()
        {
            eRoot = xmlDoc.CreateElement(ELEMENT_ROOT);
            eParent = xmlDoc.CreateElement(ELEMENT_PARENT);
            xmlPath = Directory.GetCurrentDirectory() + ESC_BACKSLASH;
            xmlFile = string.Format(LOG_FILE_NAME, DateTime.Now.ToString(LOG_FILE_NAME_DATE_FORMAT));
        }


        /// <summary>
        /// Get singleton instance
        /// </summary>
        public static XmlDaoGateway Instance
        {
            get
            {
                return xmlDaoGatewaySingleton;
            }
        }

        /// <summary>
        /// Append a message to xml hierarchy
        /// </summary>
        /// <param name="name">element name</param>
        /// <param name="message">message text</param>
        public void AppendMessage(string name, string message)
        {
            XmlElement eChild = xmlDoc.CreateElement(name);
            XmlText xmlText = xmlDoc.CreateTextNode(message);
            eChild.AppendChild(xmlText);
            eParent.AppendChild(eChild);
        }

        /// <summary>
        /// Write a message into xml file
        /// </summary>
        public string WriteMessage()
        {
            try
            {
                // Read the current XML file
                XmlDocument xmlCurrentDoc = new XmlDocument();
                xmlCurrentDoc.Load(xmlFile);

                // Add a new element to the current XML file
                XmlElement currentElment = xmlCurrentDoc.DocumentElement;
                XmlNode currentNode = xmlCurrentDoc.ImportNode(eParent, true);
                currentElment.InsertBefore(currentNode, currentElment.FirstChild);
                xmlCurrentDoc.Save(xmlFile);

                // Clean up elements
                eParent.RemoveAll();

                // Just for test
                return xmlCurrentDoc.OuterXml;

            }
            catch (FileNotFoundException )
            {
                // Create a new XML file
                eRoot.AppendChild(eParent);
                xmlDoc.AppendChild(eRoot);
                var writer = new System.Xml.XmlTextWriter(xmlPath + xmlFile, Encoding.UTF8);
                writer.WriteStartDocument();
                writer.Formatting = System.Xml.Formatting.Indented;
                xmlDoc.WriteTo(writer);
                writer.Close();

                // Preserve Node befor cleanup
                XmlNode xmlCloneNode = xmlDoc.Clone();

                // Clean up elements
                eParent.RemoveAll();

                // Just for test
                return xmlCloneNode.OuterXml;
            }
        }

    }
}
